import { join, dirname } from 'path';
import { ruleSummary, runRules, retrievePiletData, getPiletsInfo, setLogLevel, progress, log } from '../common';
import { getPiletRules } from '../rules';
import { PiletRuleContext, LogLevels } from '../types';

export interface ValidatPiletOptions {
  /**
   * Sets the root module of the pilet.
   */
  entry?: string;

  /**
   * Sets the log level to use (1-5).
   */
  logLevel?: LogLevels;

  /**
   * Overrides the Piral instance used as validation blueprint for the pilet.
   */
  app?: string;
}

export const validatePiletDefaults: ValidatPiletOptions = {
  entry: './src/index',
  logLevel: LogLevels.info,
  app: undefined,
};

export async function validatePilet(baseDir = process.cwd(), options: ValidatPiletOptions = {}) {
  const {
    entry = validatePiletDefaults.entry,
    logLevel = validatePiletDefaults.logLevel,
    app = validatePiletDefaults.app,
  } = options;
  setLogLevel(logLevel);
  progress('Reading configuration ...');

  const rules = await getPiletRules();
  const entryFile = join(baseDir, entry);
  const target = dirname(entryFile);
  const {
    dependencies,
    peerDependencies,
    devDependencies,
    peerModules,
    root,
    ignored: _0,
    emulator: _1,
    ...data
  } = await retrievePiletData(target, app);
  const { validators } = getPiletsInfo(data.appPackage);
  const errors: Array<string> = [];
  const warnings: Array<string> = [];
  const context: PiletRuleContext = {
    error(message) {
      errors.push(log('generalError_0002', message));
    },
    warning(message) {
      warnings.push(log('generalWarning_0001', message));
    },
    logLevel,
    entry: entryFile,
    dependencies,
    devDependencies,
    peerDependencies,
    peerModules,
    root,
    data,
  };

  await runRules(rules, context, validators);

  ruleSummary(errors, warnings);
}
